<template>
	<div class="min-h-[597px] pt-4 px-[25px] md:px-[35px] pb-10">
		<div class="-mx-2">
			<WalletRecentlyCurrency
				v-model:currency="selectedCurrency"
				@click:more="dropdownCurrencyRef?.onClickShow()" />
		</div>
		<template v-if="walletStore.loading.fiatDepositChannel">
			<BaseLoadingCircle class="mt-20 mx-auto" />
		</template>
		<template v-else-if="!walletStore.fiatDepositChannel?.length">
			<BaseEmpty class="mt-20" />
		</template>
		<form v-else @submit.prevent="onEnter">
			<input type="submit" class="hidden" />
			<WalletSelectCurrency
				ref="dropdownCurrencyRef"
				type="fiat"
				:options="walletStore.fiatDepositChannel"
				v-model:currency="selectedCurrency"
				v-model:currency-item="selectedCurrencyItem" />
			<template v-if="loadingShortcut">
				<BaseLoadingCircle class="mt-20 mx-auto" />
			</template>
			<template v-if="!loadingShortcut && selectedCurrencyItem">
				<div class="mb-[6px]">{{ $t('wallet.depositMethod') }}</div>
				<div v-if="!selectedChannel">
					<div
						v-for="payType in selectedCurrencyItem?.payTypeList"
						:key="payType.payTypeId"
						class="mt-2 first:mt-0 rounded-lg bg-bg-2">
						<div class="flex items-center h-12 px-3">
							{{ payType.payTypeName }}
						</div>
						<div class="h-[1px] bg-bg-1" />
						<div class="px-3 py-2">
							<div class="grid grid-cols-3 gap-2">
								<div
									v-for="item in payType.payMethodList"
									:key="item.id"
									class="h-[120px] p-2 rounded-lg bg-bg-3 text-center app-bg-react"
									@click="selectedChannel = item">
									<BaseImage
										class="w-full h-[58px] object-scale-down"
										:src="item?.appIcon"
										type="server" />
									<div class="h-5 mt-2 text-base text-t-2">{{ item?.payMethodName }}</div>
									<div class="text-sm text-t-3">
										{{ $t('deposit.estimatedMinutes', [item?.spendTime]) }}
									</div>
								</div>
							</div>
						</div>
					</div>
				</div>
				<template v-if="!!selectedChannel">
					<div class="mb-4 rounded-lg bg-bg-2">
						<div class="flex items-center h-12 px-3" @click="selectedChannel = null">
							<BaseImage
								class="h-[30px] object-scale-down"
								:src="selectedChannel?.appIcon"
								type="server" />
							<div class="ml-1">{{ selectedChannel?.payMethodName }}</div>
							<base-icon name="down" class="ml-auto text-t-3 text-[20px] duration-300" />
						</div>
					</div>
					<deposit-activity :currency-to="selectedCurrencyItem?.currency" />
					<template v-for="field in selectedChannel?.inputField || []" :key="field">
						<BaseInput
							v-if="field === 'bankAccountName'"
							labelT="wallet.cardholderName"
							v-model="formValue.bankAccountName"
							:errorT="formRule.bankAccountName.result.textT"
							:is-danger="!formRule.bankAccountName.result.valid"
							@blur="formRule.bankAccountName.validator()"
							@focus="formReset('bankAccountName')" />
						<BaseInput
							v-if="field === 'bankName'"
							labelT="wallet.bank"
							v-model="formValue.bankName"
							:errorT="formRule.bankName.result.textT"
							:is-danger="!formRule.bankName.result.valid"
							@blur="formRule.bankName.validator()"
							@focus="formReset('bankName')" />
						<BaseInput
							v-if="field === 'bankBranch'"
							labelT="wallet.bankBranch"
							v-model="formValue.bankBranch"
							:errorT="formRule.bankBranch.result.textT"
							:is-danger="!formRule.bankBranch.result.valid"
							@blur="formRule.bankBranch.validator()"
							@focus="formReset('bankBranch')" />
						<BaseInput
							v-if="field === 'bankCardNo'"
							labelT="wallet.bankcardNo"
							v-model="formValue.bankCardNo"
							type="number"
							:errorT="formRule.bankCardNo.result.textT"
							:is-danger="!formRule.bankCardNo.result.valid"
							@blur="formRule.bankCardNo.validator()"
							@focus="formReset('bankCardNo')" />
						<template v-if="field === 'amount'">
							<BaseInput
								labelT="recharge.amount"
								v-model="formValue.amount"
								type="number"
								class="!mb-1"
								:errorT="formRule.amount.result.textT"
								:is-danger="!formRule.amount.result.valid"
								@blur="formRule.amount.validator()"
								@focus="formReset('amount')">
								<template #title>
									<div class="flex items-center">
										<span>{{ $t('recharge.amount') }}</span>
										<base-amount
											class="ml-auto text-t-3 text-sm"
											:value="formValue.amount"
											:currency="selectedCurrencyItem?.currency"
											hide-currency
											reverse-fiat />
									</div>
								</template>
								<template #suffix>
									<BaseCurrency :currency="selectedCurrencyItem?.currency" />
								</template>
							</BaseInput>
							<BaseTip>
								<span>{{ $t('recharge.lowestAmount') }}:&nbsp;</span>
								<BaseAmount
									v-if="selectedCurrency"
									:value="selectedChannel?.minAmount"
									:currency="selectedCurrency" />
							</BaseTip>
							<BaseTip>
								<span>{{ $t('recharge.maxAmount') }}:&nbsp;</span>
								<BaseAmount
									v-if="selectedCurrency"
									:value="selectedChannel?.maxAmount"
									:currency="selectedCurrency" />
							</BaseTip>
							<div class="mb-4" />
						</template>
					</template>
					<div class="grid grid-cols-3 gap-2 mt-[25px]">
						<div
							v-for="item in shortcut"
							:key="item"
							class="flex items-center justify-center h-7 px-[10px] border border-bg-4 rounded-lg bg-bg-3 app-bg-react"
							:class="{ '!border-primary !bg-[#7864FF4D]': formValue.amount === item }"
							@click="formValue.amount = item">
							<span>{{ fmtNum(item) }}</span>
						</div>
					</div>
					<BaseButton
						class="mt-[25px]"
						type="primary"
						textT="wallet.deposit"
						:loading="loading"
						@click="onEnter" />
					<div class="mt-4 text-sm text-t-3">
						<div>1. {{ $t('deposit.tip1') }}</div>
						<div>2. {{ $t('deposit.tip2') }}</div>
						<div>3. {{ $t('deposit.tip3') }}</div>
					</div>
				</template>
			</template>
		</form>
	</div>
</template>

<script setup lang="ts">
import { computed, nextTick, onMounted, reactive, ref, watch } from 'vue'
import { getFiatDepositShortcutButton, submitFiatDeposit } from '@/api/wallet.ts'
import { CurrencyEnum } from '@/enums'
import {
	BaseAmount,
	BaseButton,
	BaseCurrency,
	BaseDropdown,
	BaseEmpty,
	BaseIcon,
	BaseImage,
	BaseInput,
	BaseLoadingCircle,
	BaseTip
} from '@/components/base'
import { WalletRecentlyCurrency, WalletSelectCurrency } from '@/components/wallet'
import { useWalletStore } from '@/store'
import { Action, FiatPayChannel, FiatPayMethod } from '@/types'
import { calcAmount, fmtNum, isLength } from '@/utils'
import { useRequest } from '@/hooks'
import DepositActivity from '@/views/wallet-new/wallet-deposit/deposit-activity.vue'
import { RuleType } from '@/components/base/input-rule/index.vue'

defineOptions({ name: 'ViewsWalletDepositFiat' })

const walletStore = useWalletStore()
const selectedCurrency = ref<CurrencyEnum | ''>('')
const selectedCurrencyItem = ref<FiatPayChannel>()
const dropdownCurrencyRef = ref<InstanceType<typeof BaseDropdown>>()
const selectedChannel = ref<FiatPayMethod | null>(null)
const formValue = reactive({
	bankAccountName: '',
	bankName: '',
	bankBranch: '',
	bankCardNo: '',
	amount: ''
})
const formRule = reactive({
	bankAccountName: {
		hasInput: false,
		result: <RuleType>{ valid: true },
		validator: (action?: Action) => {
			if (action === Action.reset) return (formRule.bankAccountName.result = { valid: true })
			if (action === Action.input) formRule.bankAccountName.hasInput = true
			if (action === Action.blur && !formRule.bankAccountName.hasInput) return
			const value = formValue.bankAccountName
			let msg = ''
			if (requiredField('bankAccountName')) {
				if (!value) {
					msg = 'tip.input.required'
				} else if (!isLength(value, 2, 32)) {
					msg = 'error.invalidFormat'
				}
			}
			formRule.bankAccountName.result = { textT: msg, valid: !msg }
		}
	},
	bankName: {
		hasInput: false,
		result: <RuleType>{ valid: true },
		validator: (action?: Action) => {
			if (action === Action.reset) return (formRule.bankName.result = { valid: true })
			if (action === Action.input) formRule.bankName.hasInput = true
			if (action === Action.blur && !formRule.bankName.hasInput) return
			const value = formValue.bankName
			let msg = ''
			if (requiredField('bankName')) {
				if (!value) {
					msg = 'tip.input.required'
				} else if (!isLength(value, 2, 32)) {
					msg = 'error.invalidFormat'
				}
			}
			formRule.bankName.result = { textT: msg, valid: !msg }
		}
	},
	bankBranch: {
		hasInput: false,
		result: <RuleType>{ valid: true },
		validator: (action?: Action) => {
			if (action === Action.reset) return (formRule.bankBranch.result = { valid: true })
			if (action === Action.input) formRule.bankBranch.hasInput = true
			if (action === Action.blur && !formRule.bankBranch.hasInput) return
			const value = formValue.bankBranch
			let msg = ''
			if (requiredField('bankBranch')) {
				if (!value) {
					msg = 'tip.input.required'
				} else if (!isLength(value, 2, 32)) {
					msg = 'error.invalidFormat'
				}
			}
			formRule.bankBranch.result = { textT: msg, valid: !msg }
		}
	},
	bankCardNo: {
		hasInput: false,
		result: <RuleType>{ valid: true },
		validator: (action?: Action) => {
			if (action === Action.reset) return (formRule.bankCardNo.result = { valid: true })
			if (action === Action.input) formRule.bankCardNo.hasInput = true
			if (action === Action.blur && !formRule.bankCardNo.hasInput) return
			const value = formValue.bankCardNo
			let msg = ''
			if (requiredField('bankCardNo')) {
				if (!value) {
					msg = 'tip.input.required'
				} else if (!/^\d{13,19}$/.test(value)) {
					msg = 'error.invalidFormat'
				}
			}
			formRule.bankCardNo.result = { textT: msg, valid: !msg }
		}
	},
	amount: {
		hasInput: false,
		result: <RuleType>{ valid: true },
		validator: (action?: Action) => {
			if (action === Action.reset) return (formRule.amount.result = { valid: true })
			if (action === Action.input) formRule.amount.hasInput = true
			if (action === Action.blur && !formRule.amount.hasInput) return
			const value = formValue.amount
			let msg = ''
			if (selectedCurrencyItem.value && selectedChannel.value) {
				const { currency } = selectedCurrencyItem.value
				const { minAmount, maxAmount, assetId } = selectedChannel.value
				const minDeposit = calcAmount(minAmount, assetId, walletStore.fiatOrFalse || currency)
				const maxDeposit = calcAmount(maxAmount, assetId, walletStore.fiatOrFalse || currency)
				if (!value && requiredField('amount')) {
					msg = 'tip.input.required'
				} else if (Number(value) < Math.max(0, Number(minDeposit.amount) || NaN)) {
					msg = 'wallet.cannotMinDepositAmount'
				} else if (Number(value) > (Number(maxDeposit.amount) || NaN)) {
					msg = 'wallet.cannotMaxDepositAmount'
				}
			}
			formRule.amount.result = { textT: msg, valid: !msg }
		}
	}
})

const formReset = (field: keyof typeof formRule, withValue: boolean = false) => {
	if (withValue && formValue[field]) formValue[field] = ''
	nextTick(() => {
		formRule[field]?.hasInput && (formRule[field].hasInput = false)
		formRule[field]?.validator?.(Action.reset)
	})
}

const {
	run: runShortcut,
	loading: loadingShortcut,
	data: shortcut
} = useRequest(getFiatDepositShortcutButton)
const { run, loading } = useRequest(submitFiatDeposit, {
	showError: true,
	showSuccess: true,
	onSuccess: (data: any) => {
		data?.payUrl && window.open(data.payUrl)
		walletStore.submitFiatDepositResult = data
		walletStore.show.submitFiatDepositResult = true
		walletStore.setWalletDepositShow(false)
	}
})

const requiredField = (field: string) => selectedChannel.value?.inputField?.includes?.(field)

const submitDisabled = computed(() => {
	return (
		(requiredField('bankAccountName') ? !formValue.bankAccountName : false) ||
		(requiredField('bankName') ? !formValue.bankName : false) ||
		(requiredField('bankBranch') ? !formValue.bankBranch : false) ||
		(requiredField('bankCardNo') ? !formValue.bankCardNo : false) ||
		(requiredField('amount') ? !formValue.amount : false) ||
		Object.values(formRule).some(({ result: { valid } }) => !valid)
	)
})

const onEnter = async () => {
	if (loading.value) return
	Object.values(formRule).forEach(({ validator }) => validator(Action.submit))
	await nextTick(async () => {
		if (submitDisabled.value) return
		loading.value = true
		await onSubmit()
	})
}

const onSubmit = async () => {
	const params = {
		payTypeId: selectedChannel.value?.payTypeId,
		payMethodId: selectedChannel.value?.payMethodId,
		currency: selectedChannel.value?.assetId,
		channelId: selectedChannel.value?.id,
		bankAccountName: formValue.bankAccountName || null,
		bankName: formValue.bankName || null,
		bankBranch: formValue.bankBranch || null,
		bankCardNo: formValue.bankCardNo || null,
		amount: formValue.amount || null
	}
	walletStore.submitFiatDepositParams = params
	await run(params)
}

watch(selectedChannel, () => {
	if (selectedChannel.value) {
		runShortcut({
			assetId: selectedChannel.value?.assetId,
			payMethodId: selectedChannel.value?.payMethodId
		})
	}
})

watch(selectedCurrency, () => {
	selectedChannel.value = null
})

onMounted(() => {
	walletStore.getFiatDepositChannel()
})
</script>

<style scoped></style>
